package cn.codeforfun.client;

import cn.codeforfun.generator.model.Client;
import cn.codeforfun.utils.JsonUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.SneakyThrows;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author wangbin
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class ClientVO extends Client implements ClientDetails {

    public static ClientVO fromClient(Client client) {
        ClientVO vo = new ClientVO();
        vo.setClientAccessTokenValiditySeconds(client.getClientAccessTokenValiditySeconds());
        vo.setClientAdditionalInformation(client.getClientAdditionalInformation());
        vo.setClientAuthorities(client.getClientAuthorities());
        vo.setClientAuthorizedGrantTypes(client.getClientAuthorizedGrantTypes());
        vo.setClientAutoApproveScope(client.getClientAutoApproveScope());
        vo.setClientId(client.getClientId());
        vo.setClientRefreshTokenValiditySeconds(client.getClientRefreshTokenValiditySeconds());
        vo.setClientRegisteredRedirectUri(client.getClientRegisteredRedirectUri());
        vo.setClientResourceIds(client.getClientResourceIds());
        vo.setClientScope(client.getClientScope());
        vo.setClientSecret(client.getClientSecret());
        return vo;
    }

    @Override
    public String getClientId() {
        return super.getClientId();
    }

    @Override
    public Set<String> getResourceIds() {
        if (StringUtils.isEmpty(super.getClientResourceIds())) {
            return new HashSet<>();
        } else {
            return StringUtils.commaDelimitedListToSet(super.getClientResourceIds());
        }
    }

    @Override
    public boolean isSecretRequired() {
        return !StringUtils.isEmpty(super.getClientSecret());
    }

    @Override
    public String getClientSecret() {
        return super.getClientSecret();
    }

    @Override
    public boolean isScoped() {
        return this.getScope().size() > 0;
    }

    @Override
    public Set<String> getScope() {
        return StringUtils.commaDelimitedListToSet(super.getClientScope());
    }

    @Override
    public Set<String> getAuthorizedGrantTypes() {
        return StringUtils.commaDelimitedListToSet(super.getClientAuthorizedGrantTypes());
    }

    @Override
    public Set<String> getRegisteredRedirectUri() {
        return StringUtils.commaDelimitedListToSet(super.getClientRegisteredRedirectUri());
    }

    @Override
    public Collection<GrantedAuthority> getAuthorities() {
        Set<String> set = StringUtils.commaDelimitedListToSet(super.getClientAuthorities());
        Set<GrantedAuthority> result = new HashSet<>();
        set.forEach(authority -> result.add((GrantedAuthority) () -> authority));
        return result;
    }

    @Override
    public Integer getAccessTokenValiditySeconds() {
        return super.getClientAccessTokenValiditySeconds();
    }

    @Override
    public Integer getRefreshTokenValiditySeconds() {
        return super.getClientRefreshTokenValiditySeconds();
    }

    @Override
    public boolean isAutoApprove(String scope) {
        if (super.getClientAutoApproveScope() == null) {
            return false;
        }
        return super.getClientAutoApproveScope().contains(scope);
    }

    @SneakyThrows
    @Override
    public Map<String, Object> getAdditionalInformation() {
        if (super.getClientAdditionalInformation() == null) {
            return new HashMap<>(0);
        }
        return JsonUtils.toMap(super.getClientAdditionalInformation());
    }
}
